package com.theyeasy.dvmini.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by SYSTEM on 2017/3/27.
 */
public class CommonUtil {

    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    private final static String WEIXIN_URL = "http://120.76.74.61:9090";

    /**
     * 获取系统默认时间
     * 
     * @return
     */
    public static Timestamp getTime() {
        return new Timestamp(new Date().getTime());
    }

    /**
     * 在默认时间上添加多少天
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param date
     *            天数
     * @return
     */
    public static Date addTime(Date date, int day) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);// 把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime();
        return date;
    }

    public final static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    /**
     * 按格式返回日期字符串
     * 
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param date
     * @param format
     * @return
     */
    public static String getDateFormat(Date date, String format) {
        SimpleDateFormat dateFormater = new SimpleDateFormat(format);
        return dateFormater.format(date);
    }

    /**
     * 返回json格式
     * 
     * @param cla
     * @return
     */
    public static <T> String getJson(T cla) {

        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        if (cla == null)
            return "";

        return gson.toJson(cla);

    }

    /**
     *
     * @param date
     * @return
     */
    public static String getSimpleDateFormat(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(date);
    }

    public static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    public static String JsonToObject(String result) {
        Gson gson = new Gson();
        Map<String, Object> resultMap = gson.fromJson(result, new TypeToken<Map<String, Object>>() {
        }.getType());
        String str = "{";
        for (Iterator<String> it = resultMap.keySet().iterator(); it.hasNext();) {
            String key = it.next();
            if (resultMap.get(key) != null && !resultMap.get(key).equals("")) {
                str += "\"" + key + "\":\"" + resultMap.get(key) + "\",";
            }
        }
        String newJson = str.substring(0, str.length() - 1) + "}";
        return newJson;
    }

    public static void download(String urlString, String filename, String savePath) throws Exception {
        // 构造URL
        URL url = new URL(urlString);
        // 打开连接
        URLConnection con = url.openConnection();
        // 设置请求超时为5s
        con.setConnectTimeout(5 * 1000);
        // 输入流
        InputStream is = con.getInputStream();

        // 1K的数据缓冲
        byte[] bs = new byte[1024];
        // 读取到的数据长度
        int len;
        // 输出的文件流
        File sf = new File(savePath);
        if (!sf.exists()) {
            sf.mkdirs();
        }
        OutputStream os = new FileOutputStream(sf.getPath() + "/" + filename);
        // 开始读取
        while ((len = is.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
        // 完毕，关闭所有链接
        os.close();
        is.close();
    }

    /**
     * 向指定 URL 发送POST方法的请求
     * 
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestProperty("Charset", "UTF-8");
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
            // 发送请求参数
            System.out.println(param);
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        System.out.println(result);
        return result;
    }

    public static String sendGet(String url, String param)

    {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = "";
            if (param.equals("")) {
                urlNameString = url;
            } else if (!url.contains("?")) {
                urlNameString = url + "?" + param;
            } else {
                urlNameString = url + "&" + param;
            }
            System.out.println(urlNameString);
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 建立实际的连接
            conn.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 传入data反序列化对象
     * 
     * @param <T>
     * @param <T>
     * @param data
     * @return 返回对象日期格式为yyyy-MM-dd HH:mm:ss
     * @throws Exception
     */
    public static <T> T getEntity(Object data, Class<T> cla) {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        String json = "";
        if (data instanceof String) {
            json = data.toString();
        } else {
            json = gson.toJson(data);
        }
        try {
            return gson.fromJson(json, cla);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 传入data反序列化对象
     * 
     * @param <T>
     * @param <T>
     * @param data
     * @return 返回对象日期格式为yyyy-MM-dd HH:mm:ss
     * @throws Exception
     */
    public static <T> T getEntity(Object data, Type cla) {
       return getEntity(data,cla);
    }

    /**
     * 传入data反序列化对象
     * 
     * @param <T>
     * @param <T>
     * @param data
     * @return 返回对象日期格式为yyyy-MM-dd HH:mm:ss
     * @throws Exception
     */
    public static <T> T getNewEntity(Object data, Class<T> cla) {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm").create();
        String json = "";
        if (data instanceof String) {
            json = data.toString();
        } else {
            json = gson.toJson(data);
        }
        try {
            // json=json.replace("\\", "");
            // json=json.replace("/", "");
            return gson.fromJson(json, cla);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 修改字符串中的unicode码
     * 
     * @param s
     *            源str
     * @return 修改后的str
     */
    public static String decode2(String s) {
        StringBuilder sb = new StringBuilder(s.length());
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (c == '\\' && chars[i + 1] == 'u') {
                char cc = 0;
                for (int j = 0; j < 4; j++) {
                    char ch = Character.toLowerCase(chars[i + 2 + j]);
                    if ('0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f') {
                        cc |= (Character.digit(ch, 16) << (3 - j) * 4);
                    } else {
                        cc = 0;
                        break;
                    }
                }
                if (cc > 0) {
                    i += 5;
                    sb.append(cc);
                    continue;
                }
            }
            sb.append(c);
        }
        return sb.toString();
    }

    /**
     * 发送短信, type类别 1调用微易科技网发送验证码
     */
    public static String SendSms(int type, String phone) {
        /*
         * Gson gson = new Gson(); ApiParam apiParam = new ApiParam(); Sms sms = new Sms(); sms.setPhone(phone);
         * sms.setContent(""); sms.setTempletid(1); // 短信验证码模板 apiParam = getParam(106, "Sms_SendCheckCode", sms, phone,
         * "vankehouse"); String json = gson.toJson(apiParam); String result =
         * SystemUtil.sendPost("http://m.theyeasy.com/Api/AcceptCmd", json); ResultMsg msg = gson.fromJson(result,
         * ResultMsg.class); if (msg != null) { return msg.getMsg(); }
         */
        return "";
    }

    /**
     * 发送短信, type类别 1调用微易科技网发送验证码
     */
    public static String SendRechargeSms(int type, String phone) {
        /*
         * Gson gson = new Gson(); ApiParam apiParam = new ApiParam(); Sms sms = new Sms(); sms.setPhone(phone);
         * sms.setContent(""); sms.setTempletid(type); // 短信验证码模板 apiParam = getParam(106, "Sms_SendCheckCode", sms,
         * phone, "vankehouse"); String json = gson.toJson(apiParam); String result =
         * SystemUtil.sendPost("http://m.theyeasy.com/Api/AcceptCmd", json); System.out.println(result); ResultMsg msg =
         * gson.fromJson(result, ResultMsg.class); if (msg != null) { return msg.getMsg(); }
         */
        return null;
    }

    /**
     * 验证短信验证码
     */
    public static String checkSendSms(String phone, String code) {
        /*
         * Gson gson = new Gson(); ApiParam apiParam = new ApiParam(); Sms sms = new Sms(); sms.setPhone(phone);
         * sms.setContent(code); sms.setTempletid(1); // 短信验证码模板 apiParam = getParam(106, "Sms_CheckCode", sms, phone,
         * "vankehouse"); String json = gson.toJson(apiParam); String result =
         * SystemUtil.sendPost("http://m.theyeasy.com/Api/AcceptCmd", json); ResultMsg msg = gson.fromJson(result,
         * ResultMsg.class); if (msg != null) { if (msg.getCode() != null && msg.getCode() == 0) { return "ok"; } else {
         * return msg.getMsg(); } }
         */
        return "";
    }

    /*
     * public static ApiParam getParam(Integer appid, String sendName, Object data, String nonce, String token) {
     * ApiParam apiParam = new ApiParam(); Gson gson = new Gson(); // apiComm String timestamp =
     * System.currentTimeMillis() / 1000 + ""; String headerStr = SystemUtil.getHeader(timestamp, nonce,
     * "132145xXXdasd23", token, appid); Header header = gson.fromJson(headerStr, Header.class); Cmd newCmd = new Cmd();
     * newCmd.setName(sendName); apiParam.setData(data); apiParam.setCmd(newCmd); apiParam.setHeader(header); return
     * apiParam; }
     */

    public static List<String> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> lDate = new ArrayList();
        lDate.add(df.format(beginDate));// 把开始时间加入集合
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(beginDate);

        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.MINUTE, 60);// 每次增加五分钟
            // 判断此日期是否在指定日期之后
            if (endDate.after(cal.getTime())) {
                String t = df.format(cal.getTime());
                lDate.add(t);
            } else {
                break;
            }
        }
        lDate.add(df.format(endDate));// 把结束时间加入集合
        return lDate;
    }

    // 当天一天每隔5分钟的时间
    public static List<Date> test1(Date date) {
        Date start = dayStartDate(date);// 转换为天的起始date
        Date nextDayDate = nextDay(start);// 下一天的date

        List<Date> result = new ArrayList<Date>();
        while (start.compareTo(nextDayDate) < 0) {
            result.add(start);
            // 日期加5分钟
            start = addFiveMin(start, 5);
        }

        return result;
    }

    public static Date nextDay(Date start) {
        Calendar c = Calendar.getInstance();
        c.setTime(start);
        c.add(Calendar.DATE, 1);
        return c.getTime();
    }

    public static Date dayStartDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime((Date) date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    // 日期段的一小时间隔时间
    public static List<Date> test(Date startDate, Date endDate) {

        List<Date> result = new ArrayList<Date>();
        while (startDate.compareTo(endDate) < 0) { // 判断开始于结束时期
            result.add(startDate);
            startDate = addFiveMin(startDate, 60); // 日期加60分钟
        }

        return result;
    }

    public static Date addFiveMin(Date start, int offset) {
        Calendar c = Calendar.getInstance();
        c.setTime(start);
        c.add(Calendar.MINUTE, offset);
        return c.getTime();
    }

    public static Date addone(Date d) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(d);
        calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
        d = calendar.getTime(); // 这个时间就是日期往后推一天的结果
        return d;
    }

    public static Date removeSeven(Date d) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(d);
        calendar.add(calendar.DATE, -7);// 把日期往后增加一天.整数往后推,负数往前移动
        d = calendar.getTime(); // 这个时间就是日期往后推一天的结果
        return d;
    }

    public static void main(String[] args) {

    }

    public static void sendWeiXinTicket(String appId, String ticket) {

        String url = WEIXIN_URL + "/common/" + appId + "/ticket";

        String value = ticket;
        try {

            value = URLEncoder.encode(value, "utf-8");

            String param = "ticket=" + value;

            String result = CommonUtil.sendGet(url, param);
            System.out.println("执行微信ticket更新-----" + result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void authorizerInsert(String openAppId, String appId, String refreshToken) {
        String url = WEIXIN_URL + "/authorizer/" + openAppId + "/" + appId + "/insert";

        String value = refreshToken;
        try {

            value = URLEncoder.encode(value, "utf-8");

            String param = "refreshToken=" + value;

            String result = CommonUtil.sendGet(url, param);
            System.out.println("执行微信authorizerInsert更新-----" + result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     *
     * @param openAppId
     * @param openNamem
     * @param openAppSecret
     * @param openToken
     * @param openAesKey
     */
    public static void commonInsert(String openAppId, String openNamem, String openAppSecret, String openToken,
            String openAesKey) {

        String url = WEIXIN_URL + "/common/" + openAppId + "/insert";
        // @RequestParam String openName,@RequestParam String openAppId,@RequestParam String openAppSecret,@RequestParam
        // String openToken,@RequestParam String openAesKey
        try {

            openNamem = URLEncoder.encode(openNamem, "utf-8");
            openAppSecret = URLEncoder.encode(openAppSecret, "utf-8");
            openToken = URLEncoder.encode(openToken, "utf-8");
            openAesKey = URLEncoder.encode(openAesKey, "utf-8");

            String param = "openName=" + openNamem + "&openAppSecret=" + openAppSecret + "&openToken=" + openToken
                    + "&openAesKey=" + openAesKey;

            String result = CommonUtil.sendGet(url, param);
            System.out.println("执行微信commonInsertt更新-----" + result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 取消授权
     * @param openAppId
     * @param appId
     */
    public static void cancelAuthorization(String openAppId, String appId) {
        try {
            String url = WEIXIN_URL + "/cancelAuthorization/" + openAppId + "/" + appId;
            String result = CommonUtil.sendGet(url, null);
            System.out.println("执行微信cancelAuthorization更新-----" + result);
        } catch (Exception e) {
            // TODO: handle exception

        }
    }
}

class ResultMsg {

    private Integer code;
    private String msg;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

class Sms {

    private String phone;
    private String content;
    private int templetid;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getTempletid() {
        return templetid;
    }

    public void setTempletid(int templetid) {
        this.templetid = templetid;
    }

}
